<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
        <title>AJ IAM /用户系统的架构设计与实现策略-用户系统</title>
        <meta name="description" content="轻量级用户认证系统 用户系统的架构设计与实现策略"/>
        <meta name="keywords" content="用户, 认证, 会员系统, IAM, AJ-IAM, 用户系统的架构设计与实现策略"/>
        <meta name="viewport" content="width=device-width, initial-scale=1"/>
        <link rel="preconnect" href="https://fonts.googleapis.com" />
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@200..900&family=Noto+Serif:ital,wght@0,100..900;1,100..900&display=swap&family=Noto+Sans+SC:wght@100..900&display=swap" />
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@100..900&family=Noto+Serif:ital,wght@0,100..900;1,100..900&display=swap" />
        <link rel="stylesheet" href="https://framework.ajaxjs.com/static/new-ui/css/common.css" />
        <link rel="stylesheet" href="/asset/main.css"/>
        <link rel="icon" type="image/x-icon" href="https://framework.ajaxjs.com/aj-logo/logo.ico"/>
        <script src="https://framework.ajaxjs.com/static/aj-docs/common.js"></script>
        <script>
            var _hmt = _hmt || [];
            (function() {
              var hm = document.createElement("script");
              hm.src = "https://hm.baidu.com/hm.js?54c70624d18784ca7539c358f583133d";
              var s = document.getElementsByTagName("script")[0];
              s.parentNode.insertBefore(hm, s);
            })();
        </script>
    </head>
    <body>
        <nav>
            <div>
                <div class="links">
                    <a href="/">🏠 首页</a>
                    | ⚙️ 源码:
                    <a target="_blank" href="https://github.com/lightweight-component/aj-iam">Github</a>/<a target="_blank" href="https://gitcode.com/lightweight-component/aj-iam">Gitcode</a>
                </div>
                <h1><img src="https://framework.ajaxjs.com/aj-logo/logo.png" style="vertical-align: middle;height: 45px;margin-bottom: 6px;" /> AJ IAM</h1>
                <h3>轻量级用户认证系统</h3>
            </div>
        </nav>
        <div>
            <menu>
                
                <ul>
                    <li class="selected">
                        <a href="/">首页</a>
                    </li>
                </ul>
                <h3>开发心得</h3>
                <ul>
                    <li>
                        <a href="/developer/user-cn">用户系统</a>
                    </li>
                    <li>
                        <a href="/developer/model-cn">用户权限模型</a>
                    </li>
                </ul>
                <h3>部署</h3>
                <ul>
                      <li>
                           <a href="/handbook/deploy-cn">部署方式</a>
                      </li>
                      <li>
                           <a href="/handbook/dev-cn">开发环境部署</a>
                      </li>
                </ul>

                <h3>其他</h3>
                <ul>
                    <li><a href="/misc/contact-cn">联系方式</a></li>
                </ul>
            </menu>
            <article class="aj-text chinese">
                <h1>用户系统的架构设计与实现策略</h1>
<p>作为用户系统的一部分，以下核心模块是必不可少且不容忽视的：</p>
<ul>
<li>用户注册</li>
<li>用户登录与登出</li>
<li>用户管理</li>
</ul>
<h2>设计可复用的用户系统</h2>
<p>几乎每个应用都需要一个用户系统，而为每个新项目从头开始重新实现一个显然是低效的——甚至可以说是不切实际的。这样做会导致重复劳动，并在不同系统之间产生不一致的实现。</p>
<p>因此，自然的做法是设计一个可在多个应用中复用的用户模块。那么关键问题就变成了：这样的系统应采用哪种架构方式？</p>
<p>常见的策略有两种：</p>
<h2>用户 SDK 方式</h2>
<p>将用户系统作为一个 SDK（软件开发工具包）提供，可以直接集成到每个应用程序中。在这种模式下：</p>
<ul>
<li>每个应用程序独立管理用户数据，或与一个中央数据源共享。</li>
<li>身份验证和用户管理逻辑封装在 SDK 内部。</li>
<li>此方法提供了紧密集成和灵活性，尤其适用于不同应用对用户需求略有差异的情况。</li>
</ul>
<h2>用户中心（集中式服务）方式</h2>
<p>设计一个独立运行的用户中心，它独立于任何特定的应用程序：</p>
<ul>
<li>它作为一个单独的服务运行，拥有自己的用户数据存储，但对外呈现统一的数据视图。</li>
<li>应用通过标准化接口（如 HTTP API 或 RPC 调用）访问用户相关功能。</li>
<li>这种方式将用户管理从业务应用中解耦出来，实现了集中控制、统一认证以及更易于扩展。</li>
</ul>
<p>在使用 SDK 方式时，实现单点登录（SSO）可能会面临挑战，因为用户数据通常由各个应用独立管理。这种分散性使得在各服务之间维护统一的身份变得困难。另一方面，大多数现代用户系统都是以集中式服务的形式实现的，这为用户数据和身份验证提供了单一的真实来源。基于这一观察，我们决定在我们的用户系统中采用集中式服务的方式。当然，这并不意味着 SDK 方式没有其优势。  在某些模块，例如访问控制或权限管理方面，基于 SDK 的解决方案可能仍然是更好的选择，具体取决于系统的架构和集成需求。</p>
<p>在接下来的章节中，我们将详细讨论这些模块及相关组件如何与 AJ-IAM 集成。</p>
<h2>用户注册</h2>
<p>用户注册是指为应用程序创建新用户账户的过程。在一个集中式的用户中心架构中，应用程序本身并不存储用户名、邮箱、手机号或密码等核心用户数据。这些数据完全由用户中心进行管理和存储。</p>
<p>用户中心负责处理用户注册、身份验证（登录）和访问控制。它会验证用户是否合法，并将该信息返回给应用程序。然而，当用户中心的数据库结构无法满足应用程序的具体需求时，常常会出现一个常见问题。由于用户中心数据库的结构通常是固定的，可能无法灵活地调整或扩展字段以匹配应用程序的需求。</p>
<p>一种可能的解决办法是在用户表中添加一个 JSON 类型的字段，用于存储任意数据。虽然这对于非结构化或动态数据是有用的，但对于结构化数据来说<strong>并不是理想的选择</strong>，因为它牺牲了查询性能、类型安全性和可维护性。</p>
<h3>推荐方案</h3>
<p>更好的做法是，在用户完成用户中心注册之后，将<strong>应用专属的用户信息本地存储在应用自己的数据库中</strong>。为了将本地用户数据与中心用户记录关联起来，可以添加一个类似 <code>iam_id</code> 的字段，用来引用用户中心中的用户 ID。</p>
<p>这样做的好处包括：</p>
<ul>
<li>核心身份和认证仍由用户中心掌控。</li>
<li>应用可以存储和管理符合自身业务需求的扩展用户属性。由于核心用户信息可以轻松获取，因此无需频繁调用用户中心。</li>
</ul>

            </article>
        </div>
        <footer>
             AJ-IAM，开源框架 <a href="https://framework.ajaxjs.com" target="_blank">AJ-Framework</a> 的一部分。联系方式：
             frank@ajaxjs.com，<a href="https://blog.csdn.net/zhangxin09" target="_blank">作者博客</a>
             <br />
             <br />
             Copyright © 2025 Frank Cheung. All rights reserved.
         </footer>
    </body>
</html>